package com.yuyan.openapi.controller;

import com.alibaba.fastjson2.JSONObject;
import com.yuyan.openapi.rest.YuyanRestUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * 聚合支付相关接口
 *
 * @author xm
 * @date 2024/1/21
 **/
@RestController
public class PayController {
    @Autowired
    private YuyanRestUtil yuyanRestUtil;
    @Value("${yuyan.mc_no}")
    public String mc_no;
    @Value("${yuyan.pay_callback}")
    public String pay_callback;
    @Value("${yuyan.refund_callback}")
    public String refund_callback;

    /**
     * 调用宇燕平台发起jsapi创建订单
     * 聚合支付，适用于微信公众号/小程序支付，支付宝生活号/小程序支付
     */
    @GetMapping("jsapi")
    public Object jsapi() {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("mcNo", mc_no);
        requestMap.put("orderNo", "202401230000001");
        requestMap.put("amount", "0.1");
        requestMap.put("payMethod", "WXPAY");
        requestMap.put("paySource", "MINI");
        requestMap.put("remark", "测试一下");
        requestMap.put("goodsName", "旺仔牛奶一瓶");
        requestMap.put("appId", "xx");
        requestMap.put("openId", "xx");
        requestMap.put("payTimeLimit", "2024-03-30 00:00:00");
        requestMap.put("extraCommonParam", "测试回调参数");
        requestMap.put("notifyUrl", pay_callback);
        requestMap.put("payerIp", "");
        try {
            JSONObject jsonObject = yuyanRestUtil.post(requestMap, "/v1/order/jsapi");

            if (!"Y000".equals(jsonObject.getString("code"))) {
                // todo 这是网关非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            if (!"S000".equals(jsonObject.getString("subCode"))) {
                // todo 这是业务非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("subMsg"));
            }

            // todo 拿到业务数据，继续业务处理即可，例如保存单号，然后返回给前端唤起支付等
            jsonObject.put("data", jsonObject.getJSONObject("data"));
            return jsonObject;
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    /**
     * 调用宇燕平台发起jsapi创建预下单
     * 适用于H5,APP需要发起微信/支付宝支付，使用小程序包装完成支付
     */
    @GetMapping("preJsapi")
    public Object preJsapi() {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("mcNo", mc_no);
        requestMap.put("orderNo", "202401230000002");
        requestMap.put("amount", "0.1");
        requestMap.put("payMethod", "WXPAY");
        requestMap.put("paySource", "MINI");
        requestMap.put("remark", "测试一下");
        requestMap.put("goodsName", "旺仔牛奶一瓶");
        requestMap.put("payTimeLimit", "2024-11-08 00:00:00");
        requestMap.put("extraCommonParam", "测试回调参数");
        requestMap.put("notifyUrl", pay_callback);
        requestMap.put("payerIp", "");
        requestMap.put("isMiniLink", "1"); // 1-是，2=否；是否需要支付链接，如当前应用在小程序或者公众号使用请传2，用返回的appId+path唤起插件，性能会更高！体验也最佳！
        requestMap.put("linkType", "2"); // 1-url link，2-url scheme；建议使用url scheme 体验最佳！
        try {
            JSONObject jsonObject = yuyanRestUtil.post(requestMap, "/v1/order/preJsapi");

            if (!"Y000".equals(jsonObject.getString("code"))) {
                // todo 这是网关非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            if (!"S000".equals(jsonObject.getString("subCode"))) {
                // todo 这是业务非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("subMsg"));
            }

            // todo 拿到业务数据，继续业务处理即可，例如保存单号，然后返回给前端唤起支付等
            jsonObject.put("data", jsonObject.getJSONObject("data"));
            return jsonObject;
        } catch (Exception e) {
            return e.getMessage();
        }
    }


    /**
     * 调用宇燕预下单支付接口，支付场景：
     * 1：在H5或APP调用预下单创建订单获得订单号
     * 2：使用urlLink唤起小程序支付处理页
     * 3：小程序使用宇燕订单号+小程序服务端获取用户openId
     * 4：调用该接口获得小程序支付参数唤起完成支付
     *
     * @return
     */
    @GetMapping("jsApiPrePay")
    public Object jsApiPrePay() {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("mcNo", mc_no);
        requestMap.put("orderNo", "202401230000001");
        requestMap.put("tradeNo", "SDYY2024012800000001");
        requestMap.put("appId", "xx");
        requestMap.put("openId", "xx");
        try {
            JSONObject jsonObject = yuyanRestUtil.post(requestMap, "/v1/order/jsApiPrePay");

            if (!"Y000".equals(jsonObject.getString("code"))) {
                // todo 这是网关非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            if (!"S000".equals(jsonObject.getString("subCode"))) {
                // todo 这是业务非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("subMsg"));
            }

            // todo 拿到业务数据，继续业务处理即可，例如保存单号，然后返回给前端唤起支付等
            jsonObject.put("data", jsonObject.getJSONObject("data"));
            return jsonObject;
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    /**
     * 调用宇燕平台发起H5创建订单
     * 适用于在手机游览器需要唤起支付，目前只支持支付宝支付
     */
    @GetMapping("h5Pay")
    public Object h5Pay() {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("mcNo", mc_no);
        requestMap.put("orderNo", "202401230000001");
        requestMap.put("amount", "0.1");
        requestMap.put("payMethod", "ALIPAY");
        requestMap.put("remark", "测试一下");
        requestMap.put("goodsName", "旺仔牛奶一瓶");
        requestMap.put("payTimeLimit", "2024-11-10 00:00:00");
        requestMap.put("extraCommonParam", "测试回调参数");
        requestMap.put("notifyUrl", pay_callback);
        requestMap.put("payerIp", "");
        try {
            JSONObject jsonObject = yuyanRestUtil.post(requestMap, "/v1/order/h5Pay");

            if (!"Y000".equals(jsonObject.getString("code"))) {
                // todo 这是网关非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            if (!"S000".equals(jsonObject.getString("subCode"))) {
                // todo 这是业务非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("subMsg"));
            }

            // todo 拿到业务数据，继续业务处理即可，例如保存单号，然后返回给前端唤起支付等
            jsonObject.put("data", jsonObject.getJSONObject("data"));
            return jsonObject;
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    /**
     * 调用宇燕平台发起付款码支付
     */
    @GetMapping("barcodePay")
    public Object barcodePay() {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("mcNo", mc_no);
        requestMap.put("orderNo", "202401230000001");
        requestMap.put("amount", "0.1");
        requestMap.put("payMethod", "WXPAY");
        requestMap.put("authCode", "xx");
        requestMap.put("terminalNo", "00000000");
        requestMap.put("remark", "测试一下");
        requestMap.put("goodsName", "旺仔牛奶一瓶");
        requestMap.put("extraCommonParam", "测试回调参数");
        requestMap.put("notifyUrl", pay_callback);
        requestMap.put("payerIp", "");
        try {
            JSONObject jsonObject = yuyanRestUtil.post(requestMap, "/v1/order/barcodePay");

            if (!"Y000".equals(jsonObject.getString("code"))) {
                // todo 这是网关非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            if (!"S000".equals(jsonObject.getString("subCode"))) {
                // todo 这是业务非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("subMsg"));
            }

            // todo 拿到业务数据，继续业务处理即可，例如保存单号，然后返回给前端唤起支付等
            jsonObject.put("data", jsonObject.getJSONObject("data"));
            return jsonObject;
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    /**
     * 调用宇燕平台发起订单查询
     */
    @GetMapping("queryOrder")
    public Object queryOrder() {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("mcNo", mc_no);
        requestMap.put("orderNo", "202401230000001");
        requestMap.put("tradeNo", "SDYY2024120600000006");
        try {
            JSONObject jsonObject = yuyanRestUtil.post(requestMap, "/v1/order/queryOrder");

            if (!"Y000".equals(jsonObject.getString("code"))) {
                // todo 这是网关非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            if (!"S000".equals(jsonObject.getString("subCode"))) {
                // todo 这是业务非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("subMsg"));
            }

            // todo 拿到业务数据，继续业务处理即可，例如保存单号，然后返回给前端唤起支付等
            jsonObject.put("data", jsonObject.getJSONObject("data"));
            return jsonObject;
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    /**
     * 调用宇燕平台发起订单退款
     */
    @GetMapping("refund")
    public Object refund() {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("mcNo", mc_no);
        requestMap.put("orderNo", "202401230000001");
        requestMap.put("tradeNo", "SDYY2024032000000028");
        requestMap.put("refundOrderNo", "R20240124000001");
        requestMap.put("amount", "0.1");
        requestMap.put("refundReason", "测试退款");
        requestMap.put("notifyUrl", refund_callback);
        try {
            JSONObject jsonObject = yuyanRestUtil.post(requestMap, "/v1/order/refund");

            if (!"Y000".equals(jsonObject.getString("code"))) {
                // todo 这是网关非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            if (!"S000".equals(jsonObject.getString("subCode"))) {
                // todo 这是业务非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("subMsg"));
            }

            // todo 拿到业务数据，继续业务处理即可，例如保存单号，然后返回给前端唤起支付等
            jsonObject.put("data", jsonObject.getJSONObject("data"));
            return jsonObject;
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    /**
     * 调用宇燕平台发起退款订单查询
     */
    @GetMapping("queryRefundOrder")
    public Object queryRefundOrder() {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("mcNo", mc_no);
        requestMap.put("orderNo", "202401230000001");
        requestMap.put("tradeNo", "SDYY2024032000000028");
        requestMap.put("refundOrderNo", "R20240124000001");
        requestMap.put("tradeRefundOrderNo", "SDYYR2024032000000021");
        try {
            JSONObject jsonObject = yuyanRestUtil.post(requestMap, "/v1/order/queryRefundOrder");

            if (!"Y000".equals(jsonObject.getString("code"))) {
                // todo 这是网关非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            if (!"S000".equals(jsonObject.getString("subCode"))) {
                // todo 这是业务非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("subMsg"));
            }

            // todo 拿到业务数据，继续业务处理即可，例如保存单号，然后返回给前端唤起支付等
            jsonObject.put("data", jsonObject.getJSONObject("data"));
            return jsonObject;
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    /**
     * 调用宇燕平台发起订单取消
     */
    @GetMapping("cancel")
    public Object cancel() {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("mcNo", mc_no);
        requestMap.put("orderNo", "202401230000001");
        requestMap.put("tradeNo", "SDYY2024022600000016");
        try {
            JSONObject jsonObject = yuyanRestUtil.post(requestMap, "/v1/order/cancel");

            if (!"Y000".equals(jsonObject.getString("code"))) {
                // todo 这是网关非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            if (!"S000".equals(jsonObject.getString("subCode"))) {
                // todo 这是业务非成功的返回，做一些逻辑处理，具体状态码可查看文档
                throw new RuntimeException(jsonObject.getString("subMsg"));
            }

            // todo 拿到业务数据，继续业务处理即可，例如保存单号，然后返回给前端唤起支付等
            jsonObject.put("data", jsonObject.getJSONObject("data"));
            return jsonObject;
        } catch (Exception e) {
            return e.getMessage();
        }
    }
}
